#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
// 全局数据类型定义
#define ElemType int
#define ElemTypes char
#define ERRLOG(errmsg)                                       \
    do                                                       \
    {                                                        \
        printf("%s--%s(%d):", __FILE__, __func__, __LINE__); \
        perror(errmsg);                                      \
        exit(-1);                                            \
    } while (0)
// 主函数
ElemType main(int argc, const char *argv[])
{
    // 检测命令行参数个数
    if (3 != argc)
    {
        printf("Usage : %s <IP地址> <接口号>\n", argv[0]);
        exit(-1);
    }
    // 打印欢迎信息
    printf("---欢迎使用聊天系统---\n");
    // 创建套接字
    ElemType sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sockfd)
        ERRLOG("套接字创建失败");
    printf("---创建套接字成功---\n");
    // 填充服务器网络信息结构体
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    // 端口号
    server_addr.sin_port = htons(atoi(argv[2]));
    // IP地址
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);
    if (INADDR_NONE == server_addr.sin_addr.s_addr)
        ERRLOG("IP地址转换失败");
    // 结构体长度
    socklen_t server_addr_len = sizeof(server_addr);
    printf("---填充服务器网络信息结构体成功---\n");
    // 与服务器建立连接
    if (-1 == connect(sockfd, (struct sockaddr *)&server_addr, server_addr_len))
        ERRLOG("connect error");
    printf("---连接服务器成功---\n");
    char buff[128] = {0};
    while (1)
    {
        scanf("%s", buff);
        int ret = 0;
        if (0 > (ret = send(sockfd, buff, sizeof(buff), 0)))
            ERRLOG("发送数据失败");
        if (0 == strcmp(buff, "quit"))
            break;
        if (0 > (ret = recv(sockfd, buff, sizeof(buff), 0)))
            ERRLOG("接收数据失败");
        printf("收到服务器回复:[%s]\n", buff);
    }
    // 关闭套接字
    close(sockfd);
    printf("---关闭套接字成功---\n");
    return 0;
}
